//!Send 和 Sync
//std::marker 模块中，有两个 trait：Send 和 Sync，它们与多线程安全相关。
//标记为 marker trait 的 trait，它实际就是一种约定，没有方法的定义，也没有关联元素（associated items）。
// 仅仅是一种约定，实现了它的类型必须满足这种约定。一种类型是否加上这种约定，要么是编译器的行为，要么是人工手动的行为。

//Send 和 Sync 在大部分情况下（针对 Rust 的基础类型和 std 中的大部分类型），会由编译器自动推导出来。
// 对于不能由编译器自动推导出来的类型，要使它们具有 Send 或 Sync 的约定，可以由人手动实现。实现的时候，
// 必须使用 unsafe 前缀，因为 Rust 默认不信任程序员，由程序员自己控制的东西，统统标记为 unsafe，
// 出了问题（比如，把不是线程安全的对象加上 Sync 约定）由程序员自行负责。

//它们的定义如下：
//
// 如果 T: Send，那么将 T 传到另一个线程中时（按值传送），不会导致数据竞争或其它不安全情况。
//
// Send 是对象可以安全发送到另一个执行体中；
// Send 使被发送对象可以和产生它的线程解耦，防止原线程将此资源释放后，在目标线程中使用出错（use after free）。
// 如果 T: Sync，那么将 &T 传到另一个线程中时，不会导致数据竞争或其它不安全情况。
//
// Sync 是可以被同时多个执行体访问而不出错；
// Sync 防止的是竞争；

//推论：
//
// T: Sync 意味着 &T: Send；
// Sync + Copy = Send；
// 当 T: Send 时，可推导出 &mut T: Send；
// 当 T: Sync 时，可推导出 &mut T: Sync；
// 当 &mut T: Send 时，不能推导出 T: Send；
// （注：T, &T, &mut T，Box<T> 等都是不同的类型）
//
// 具体的类型：
//
// 原始类型（比如： u8, f64），都是 Sync，都是 Copy，因此都是 Send；
// 只包含原始类型的复合类型，都是 Sync，都是 Copy，因此都是 Send；
// 当 T: Sync，Box<T>, Vec<T> 等集合类型是 Sync；
// 具有内部可变性的的指针，不是 Sync 的，比如 Cell, RefCell, UnsafeCell；
// Rc 不是 Sync。因为只要一做 &Rc<T> 操作，就会克隆一个新引用，它会以非原子性的方式修改引用计数，所以是不安全的；
// 被 Mutex 和 RWLock 锁住的类型 T: Send，是 Sync 的；
// 原始指针（*mut, *const）既不是 Send 也不是 Sync；